From aa2c5565dc0725cf69771f376c9bec03b3524362 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 23 Oct 2008 11:17:25 +0100 Subject: [PATCH] Xen power management daemon patch. Signed-off-by: Kamala Narasimhan --- tools/Makefile | 1 + tools/xenpmd/Makefile | 15 ++ tools/xenpmd/xenpmd | Bin 0 -> 26838 bytes tools/xenpmd/xenpmd.c | 520 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 536 insertions(+) create mode 100644 tools/xenpmd/Makefile create mode 100755 tools/xenpmd/xenpmd create mode 100644 tools/xenpmd/xenpmd.c diff --git a/tools/Makefile b/tools/Makefile index 4d27b26fe0..09964323e9 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -24,6 +24,7 @@ SUBDIRS-y += libfsimage SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen SUBDIRS-y += fs-back SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir +SUBDIRS-y += xenpmd # These don't cross-compile ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH)) diff --git a/tools/xenpmd/Makefile b/tools/xenpmd/Makefile new file mode 100644 index 0000000000..0e9f54040c --- /dev/null +++ b/tools/xenpmd/Makefile @@ -0,0 +1,15 @@ +XEN_ROOT=../.. +include $(XEN_ROOT)/tools/Rules.mk + +CFLAGS += -Werror +CFLAGS += $(CFLAGS_libxenstore) +LDFLAGS += $(LDFLAGS_libxenstore) + +BIN = xenpmd + +.PHONY: all +all: $(BIN) + +.PHONY: clean +clean: + $(RM) -f $(BIN) diff --git a/tools/xenpmd/xenpmd b/tools/xenpmd/xenpmd new file mode 100755 index 0000000000000000000000000000000000000000..034050c578b6724ceb426c5f474cd84480759a0d GIT binary patch literal 26838 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

bIcV6>*^PxA)HP0aRFDf;z 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 G;(q~ +#include +#include +#include +#include +#include +#include +#include + +/* #define RUN_STANDALONE */ +#define RUN_IN_SIMULATE_MODE + +enum BATTERY_INFO_TYPE { + BIF, + BST +}; + +enum BATTERY_PRESENT { + NO, + YES +}; + +enum BATTERY_TECHNOLOGY { + NON_RECHARGEABLE, + RECHARGEABLE +}; + +struct battery_info { + enum BATTERY_PRESENT present; + unsigned long design_capacity; + unsigned long last_full_capacity; + enum BATTERY_TECHNOLOGY battery_technology; + unsigned long design_voltage; + unsigned long design_capacity_warning; + unsigned long design_capacity_low; + unsigned long capacity_granularity_1; + unsigned long capacity_granularity_2; + char model_number[32]; + char serial_number[32]; + char battery_type[32]; + char oem_info[32]; +}; + +struct battery_status { + enum BATTERY_PRESENT present; + unsigned long state; + unsigned long present_rate; + unsigned long remaining_capacity; + unsigned long present_voltage; +}; + +static struct xs_handle *xs; + +#ifdef RUN_IN_SIMULATE_MODE + #define BATTERY_DIR_PATH "/tmp/battery" + #define BATTERY_INFO_FILE_PATH "/tmp/battery/%s/info" + #define BATTERY_STATE_FILE_PATH "/tmp/battery/%s/state" +#else + #define BATTERY_DIR_PATH "/proc/acpi/battery" + #define BATTERY_INFO_FILE_PATH "/proc/acpi/battery/%s/info" + #define BATTERY_STATE_FILE_PATH "/proc/acpi/battery/%s/state" +#endif + +FILE *get_next_battery_file(DIR *battery_dir, + enum BATTERY_INFO_TYPE battery_info_type) +{ + FILE *file = 0; + struct dirent *dir_entries; + char file_name[32]; + + do + { + dir_entries = readdir(battery_dir); + if ( !dir_entries ) + return 0; + if ( strlen(dir_entries->d_name) < 4 ) + continue; + if ( battery_info_type == BIF ) + snprintf(file_name, 32, BATTERY_INFO_FILE_PATH, + dir_entries->d_name); + else + snprintf(file_name, 32, BATTERY_STATE_FILE_PATH, + dir_entries->d_name); + file = fopen(file_name, "r"); + } while ( !file ); + + return file; +} + +void set_attribute_battery_info(char *attrib_name, + char *attrib_value, + struct battery_info *info) +{ + if ( strstr(attrib_name, "present") ) + { + if ( strstr(attrib_value, "yes") ) + info->present = YES; + return; + } + + if ( strstr(attrib_name, "design capacity warning") ) + { + info->design_capacity_warning = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "design capacity low") ) + { + info->design_capacity_low = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "design capacity") ) + { + info->design_capacity = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "last full capacity") ) + { + info->last_full_capacity = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "design voltage") ) + { + info->design_voltage = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "capacity granularity 1") ) + { + info->capacity_granularity_1 = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "capacity granularity 2") ) + { + info->capacity_granularity_2 = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "battery technology") ) + { + if ( strncmp(attrib_value, "rechargeable", + strlen("rechargeable")) == 0 ) + info->battery_technology = RECHARGEABLE; + else + info->battery_technology = NON_RECHARGEABLE; + return; + } + + if ( strstr(attrib_name, "model number") ) + { + strncpy(info->model_number, attrib_value, 32); + return; + } + + if ( strstr(attrib_name, "serial number") ) + { + strncpy(info->serial_number, attrib_value, 32); + return; + } + + if ( strstr(attrib_name, "battery type") ) + { + strncpy(info->battery_type, attrib_value, 32); + return; + } + + if ( strstr(attrib_name, "OEM info") ) + { + strncpy(info->oem_info, attrib_value, 32); + return; + } + + return; +} + +void set_attribute_battery_status(char *attrib_name, + char *attrib_value, + struct battery_status *status) +{ + if ( strstr(attrib_name, "charging state") ) + { + /* Check this, below is half baked */ + if ( strstr(attrib_value, "charged") ) + status->state = 0; + else + status->state = 1; + return; + } + + if ( strstr(attrib_name, "present rate") ) + { + status->present_rate = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "remaining capacity") ) + { + status->remaining_capacity = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "present voltage") ) + { + status->present_voltage = strtoull(attrib_value, NULL, 10); + return; + } + + if ( strstr(attrib_name, "present") ) + { + if ( strstr(attrib_value, "yes") ) + status->present = YES; + return; + } +} + +void parse_battery_info_or_status(char *line_info, + enum BATTERY_INFO_TYPE type, + void *info_or_status) +{ + char attrib_name[128]; + char attrib_value[64]; + char *delimiter; + unsigned long length; + + length = strlen(line_info); + delimiter = (char *) strchr( line_info, ':'); + if ( (!delimiter) || (delimiter == line_info) || + (delimiter == line_info + length) ) + return; + + strncpy(attrib_name, line_info, delimiter-line_info); + while ( *(delimiter+1) == ' ' ) + { + delimiter++; + if ( delimiter+1 == line_info + length) + return; + } + strncpy(attrib_value, delimiter+1, + (unsigned long)line_info + length -(unsigned long)delimiter); + + if ( type == BIF ) + set_attribute_battery_info(attrib_name, attrib_value, + (struct battery_info *)info_or_status); + else + set_attribute_battery_status(attrib_name, attrib_value, + (struct battery_status *)info_or_status); + + return; +} + +int get_next_battery_info_or_status(DIR *battery_dir, + enum BATTERY_INFO_TYPE type, + void *info_or_status) +{ + FILE *file; + char line_info[256]; + + if ( !info_or_status ) + return 0; + + memset(line_info, 0, 256); + if (type == BIF) + memset(info_or_status, 0, sizeof(struct battery_info)); + else + memset(info_or_status, 0, sizeof(struct battery_status)); + + file = get_next_battery_file(battery_dir, type); + if ( !file ) + return 0; + + while ( fgets(line_info, 1024, file) != NULL ) + { + parse_battery_info_or_status(line_info, type, info_or_status); + memset(line_info, 0, 256); + } + + fclose(file); + return 1; +} + +#ifdef RUN_STANDALONE +void print_battery_info(struct battery_info *info) +{ + printf("present: %d\n", info->present); + printf("design capacity: %d\n", info->design_capacity); + printf("last full capacity: %d\n", info->last_full_capacity); + printf("battery technology: %d\n", info->battery_technology); + printf("design voltage: %d\n", info->design_voltage); + printf("design capacity warning:%d\n", info->design_capacity_warning); + printf("design capacity low: %d\n", info->design_capacity_low); + printf("capacity granularity 1: %d\n", info->capacity_granularity_1); + printf("capacity granularity 2: %d\n", info->capacity_granularity_2); + printf("model number: %s\n", info->model_number); + printf("serial number: %s\n", info->serial_number); + printf("battery type: %s\n", info->battery_type); + printf("OEM info: %s\n", info->oem_info); +} +#endif /*RUN_STANDALONE*/ + +void write_ulong_lsb_first(char *temp_val, unsigned long val) +{ + snprintf(temp_val, 9, "%02x%02x%02x%02x", (unsigned int)val & 0xff, + (unsigned int)(val & 0xff00) >> 8, (unsigned int)(val & 0xff0000) >> 16, + (unsigned int)(val & 0xff000000) >> 24); +} + +void write_battery_info_to_xenstore(struct battery_info *info) +{ + char val[1024], string_info[256]; + + xs_mkdir(xs, XBT_NULL, "/pm"); + + memset(val, 0, 1024); + memset(string_info, 0, 256); + /* write 9 dwords (so 9*4) + length of 4 strings + 4 null terminators */ + snprintf(val, 3, "%02x", + (unsigned int)(9*4 + + strlen(info->model_number) + + strlen(info->serial_number) + + strlen(info->battery_type) + + strlen(info->oem_info) + 4)); + write_ulong_lsb_first(val+2, info->present); + write_ulong_lsb_first(val+10, info->design_capacity); + write_ulong_lsb_first(val+18, info->last_full_capacity); + write_ulong_lsb_first(val+26, info->battery_technology); + write_ulong_lsb_first(val+34, info->design_voltage); + write_ulong_lsb_first(val+42, info->design_capacity_warning); + write_ulong_lsb_first(val+50, info->design_capacity_low); + write_ulong_lsb_first(val+58, info->capacity_granularity_1); + write_ulong_lsb_first(val+66, info->capacity_granularity_2); + + snprintf(string_info, 256, "%02x%s%02x%s%02x%s%02x%s", + (unsigned int)strlen(info->model_number), info->model_number, + (unsigned int)strlen(info->serial_number), info->serial_number, + (unsigned int)strlen(info->battery_type), info->battery_type, + (unsigned int)strlen(info->oem_info), info->oem_info); + strncat(val+73, string_info, 1024); + xs_write(xs, XBT_NULL, "/pm/bif", + val, 73+8+strlen(info->model_number)+strlen(info->serial_number)+ + strlen(info->battery_type)+strlen(info->oem_info)+1); +} + +int write_one_time_battery_info(void) +{ + DIR *dir; + int ret = 0; + struct battery_info info; + + dir = opendir(BATTERY_DIR_PATH); + if ( !dir ) + return 0; + + while ( get_next_battery_info_or_status(dir, BIF, (void *)&info) ) + { +#ifdef RUN_STANDALONE + print_battery_info(&info); +#endif + if ( info.present == YES ) + { + write_battery_info_to_xenstore(&info); + ret = 1; + break; /* rethink this... */ + } + } + + closedir(dir); + return ret; +} + +#ifdef RUN_STANDALONE +void print_battery_status(struct battery_status *status) +{ + printf("present: %d\n", status->present); + printf("Battery state %d\n", status->state); + printf("Battery present rate %d\n", status->present_rate); + printf("Battery remining capacity %d\n", status->remaining_capacity); + printf("Battery present voltage %d\n", status->present_voltage); +} +#endif /*RUN_STANDALONE*/ + +void write_battery_status_to_xenstore(struct battery_status *status) +{ + char val[35]; + + xs_mkdir(xs, XBT_NULL, "/pm"); + + memset(val, 0, 35); + snprintf(val, 3, "%02x", 16); + write_ulong_lsb_first(val+2, status->state); + write_ulong_lsb_first(val+10, status->present_rate); + write_ulong_lsb_first(val+18, status->remaining_capacity); + write_ulong_lsb_first(val+26, status->present_voltage); + + xs_write(xs, XBT_NULL, "/pm/bst", val, 35); +} + +int wait_for_and_update_battery_status_request(void) +{ + DIR *dir; + int ret = 0; + unsigned int count; + struct battery_status status; + + while ( true ) + { + /* KN:@TODO - It is rather inefficient to not cache the file handle. + * Switch to caching file handle. + */ + dir = opendir(BATTERY_DIR_PATH); + if ( !dir ) + return 0; + + while ( get_next_battery_info_or_status(dir, BST, (void *)&status) ) + { +#ifdef RUN_STANDALONE + print_battery_status(&status); +#endif + if ( status.present == YES ) + { + write_battery_status_to_xenstore(&status); + ret = 1; + /* rethink this; though I have never seen, there might be + * systems out there with more than one battery device + * present + */ + break; + } + } + closedir(dir); + xs_watch(xs, "/pm/events", "refreshbatterystatus"); + xs_read_watch(xs, &count); + } + + return ret; +} + +/* Borrowed daemonize from xenstored - Initially written by Stevens. */ +static void daemonize(void) +{ + pid_t pid; + + if ( (pid = fork()) < 0 ) + exit(1); + + if ( pid != 0 ) + exit(0); + + setsid(); + + if ( (pid = fork()) < 0 ) + exit(1); + + if ( pid != 0 ) + exit(0); + + if ( chdir("/") == -1 ) + exit(1); + + umask(0); +} + +int main(int argc, char *argv[]) +{ +#ifndef RUN_STANDALONE + daemonize(); +#endif + xs = (struct xs_handle *)xs_daemon_open(); + if ( xs == NULL ) + return -1; + + if ( write_one_time_battery_info() == 0 ) + { + xs_daemon_close(xs); + return -1; + } + + wait_for_and_update_battery_status_request(); + xs_daemon_close(xs); + return 0; +} + -- 2.30.2